package com.le.book.util;

import java.io.IOException;
import java.io.InputStream;
import java.sql.*;
import java.util.*;

/**
 * ���ݿ����������, �����ݿ����, ͨ���򵥵�����SQL���Ͳ���, ִ�в����ؽ��
 */
public class DBHelper {

	// ������·��
    protected static String driver;
    // ���Ӵ�
    protected static String url;
    // �û���
    protected static String user;
    // ����
    protected static String password;
    
    // ��̬�飺һ������������һ��
    static {
    	
    	try {
    		// ��ʼ�����ݿ����ò���
    		Properties prop = new Properties(); // Map������
    		// ��ȡ�������
    		ClassLoader classLoader = DBHelper.class.getClassLoader();
    		// ��ȡ��Ŀ��Ŀ¼�������ļ�
    		InputStream in = classLoader.getResourceAsStream("jdbc1.properties");
    		
    		if(in == null) {
    			throw new IOException("�����ļ������ڣ�");
    		}
    		
    		prop.load(in);
    		driver = prop.getProperty("driver");
    		url = prop.getProperty("url");
    		user = prop.getProperty("username");
    		password = prop.getProperty("password");
    		
    		Class.forName(driver);
    	} catch (ClassNotFoundException e) {
    		throw new RuntimeException("���ݿ���������ʧ�ܣ�", e);
    	} catch (IOException e) {
    		
			throw new RuntimeException("���ݿ������ļ� jdbc1.properties ����ʧ�ܣ�", e);
		}
    }
    

    /**
     * ��ȡ����
     */
    public static Connection getConnection(){
        
    	try {
    		// ���سɹ�
    		// Class.forName("orcle.jdbc.driver.OracleDriver");
    		
    		// ��������
    		return DriverManager.getConnection(url, user, password);
    		
    	} catch (Exception e) {
    		// �쳣ת�� ==> �쳣��
    		throw new RuntimeException(e);
    	}
    	
    }

    /**
     * �������ݿ�
     */
    public static int update(String sql, Object... params) throws SQLException {
        try (Connection conn = getConnection();){
        	// �������
        	PreparedStatement ps = conn.prepareStatement(sql);
        	// ���ò���
        	for (int i=0; i<params.length; i++) {
        		ps.setObject(i+1, params[i]);
        	}
        	// ִ�����
        	return ps.executeUpdate();
        }
    }

    /**
     * ��ѯ��������, ����List<Map>����
     */
    public static List<Map<String, Object>> selectListMap(String sql, Object... params) throws SQLException {
        try(Connection conn = getConnection();){
        	// �������
        	PreparedStatement ps = conn.prepareStatement(sql);
        	// ���ò���
        	for (int i=0; i<params.length; i++) {
        		ps.setObject(i+1, params[i]);
        	}
        	ResultSet rs = ps.executeQuery();
        	// ���ؽ������Ԫ���ݡ�����
        	ResultSetMetaData rsmd = rs.getMetaData(); 
        	// ���ؽ�������е�����
        	int columnCount  = rsmd.getColumnCount();
        	
        	// �������صļ��϶���
        	List<Map<String, Object>> list = new ArrayList<>();
        	
        	while (rs.next()) {
        		// ����map����
        		Map<String, Object> row = new LinkedHashMap<>();
        		for (int i=0; i<columnCount; i++) {
        			String columnName = rsmd.getColumnName(i+1);
        			Object columnValue = rs.getObject(i+1);
        			row.put(columnName, columnValue);
        		}
        		// ���������ݶ������ list ����
        		list.add(row);
        	}
        	return list;
        }
    	
    }

    /**
     * ��ѯ��������, ����Map����
     */
    public static Map<String, Object> selectOneMap(String sql, Object... params) throws SQLException {
    	try(Connection conn = getConnection();){
        	// �������
        	PreparedStatement ps = conn.prepareStatement(
        			sql, 
        			ResultSet.TYPE_SCROLL_INSENSITIVE,  // ���ÿɹ�������� ������
        			ResultSet.CONCUR_READ_ONLY);        // ֻ�������
        	// ���ò���
        	for (int i=0; i<params.length; i++) {
        		ps.setObject(i+1, params[i]);
        	}
        	ResultSet rs = ps.executeQuery();
        	// ���ؽ������Ԫ���ݡ�����
        	ResultSetMetaData rsmd = rs.getMetaData(); 
        	// ���ؽ�������е�����
        	int columnCount  = rsmd.getColumnCount();
        	
        	// �жϽ���������Ƿ���ȷ
        	// 1.�Ƿ�Ϊ��
        	if (!rs.next()) {
        		return null;
        	}
        	// 2.�Ƿ����1
        	if(rs.next()) { // ������һ������û����
        		// IllegalStateException ����״̬����ȷ���쳣
        		throw new IllegalStateException("���������1��");
        	}
        	
        	// �����α�ص���һ����ע��Ĭ�Ͻ�������ܻ��ߣ�Ҫ���ÿɹ��������
        	rs.previous();
        	
        	// �������صļ��϶���
        	Map<String, Object> row = new LinkedHashMap<>();
        	for (int i=0; i<columnCount; i++) {
        		String columnName = rsmd.getColumnName(i+1);
        		Object columnValue = rs.getObject(i+1);
        		row.put(columnName, columnValue);
        	}
        	return row;
        }
    }

    /**
     * ��ѯ��������, ����List<T>����, T Ϊʵ�������
     */
    public static <T> List<T> selectListBean(String sql, Class<T> cls, Object... params) throws SQLException {
        return null;
    }

    /**
     * ��ѯ��������, ����T����, T Ϊʵ�������
     */
    public static <T> T selectOneBean(String sql, Class<T> cls, Object... params) throws SQLException {
        return null;
    }

    /**
     * ��ѯ��ҳ����
     */
    public static Page<Map<String, Object>> selectPage(String sql, int page, int size, Object... params) throws SQLException {
        return null;
    }

    /**
     * ����ģ�巽��
     */
    public <T> T execute(SqlHandler handler) {
        return null;
    }

    /**
     * ִ��SQL���� �����ӿ�
     */
    public static interface SqlHandler<T> {
        T handle(Connection connection);
    }

    public static class Page<E> {

        /**
         * ��ǰҳ��
         */
        private int page = 1;
        /**
         * ÿҳ����
         */
        private int size = 10;
        /**
         * ������ܼ�¼��
         */
        private int rows;
        /**
         * �������ҳ��
         */
        private int pages;
        /**
         * ��ѯ����ǰҳ������
         */
        private List<E> data;

        public Page(int page, int size) {
            this.page = page;
            this.size = size;
        }

        public void setData(List<E> data, int rows) {
            this.data = data;
            this.rows = rows;
            // ������ҳ��
            this.pages = rows / size;
            pages += rows % size == 0 ? 0 : 1;
        }

        /**
         * ����ǰ��ҳ��ҳ��
         *
         * @return
         */
        public int nextPage() {
            return page == pages ? page : (page + 1);
        }

        /**
         * ����ǰһҳ��ҳ��
         *
         * @return
         */
        public int priorPage() {
            return page == 1 ? page : (page - 1);
        }

        public int getPage() {
            return page;
        }

        public int getSize() {
            return size;
        }

        public int getRows() {
            return rows;
        }

        public int getPages() {
            return pages;
        }

        public List<E> getData() {
            return data;
        }
    }
	
	
	
	public static void main(String[] args) throws SQLException {
		update("update emp set ename = '����1' where empno = 8848");
		
		/*System.out.println(getConnection());
		
		
		
		try {
			java.sql.Date date = new java.sql.Date(1999,10,10);
			update("update emp set comm=comm+1000 where empno = ?", 8848);
			update("insert into emp values(?, ?, ?, ?, ?, ?, ?, ?)", 8858, "����", "����ʵϰ", "8848", date, 1000, null, 60);
		} catch (SQLException e) {
			// TODO Auto-generated catch block
			e.printStackTrace();
		}*/
		
		List<Map<String, Object>> list = selectListMap("select * from emp where empno > ?", 7788);
		
		for (Map<String, Object> row : list) {
			System.out.println(row);
		}

	}

}
